
appdu = {}
appdu[1]= "LINK-Request(预连接请求)"
appdu[2]= "CONNECT-Request(建立应用连接请求)"
appdu[3]= "RELEASE-Request(断开应用连接请求)"
appdu[5]= "GET-Request(读取请求)"
appdu[6]= "SET-Request(设置请求)"
appdu[7]= "ACTION-Request(操作请求)"
appdu[8]= "REPORT-Response(上报应答)"
appdu[9]= "PROXY-Request(代理请求)"

appdu[16]= "SECURITY-Request(安全请求)"
appdu[144]= "SECURITY-Response(安全响应)"

appdu[129]= "LINK-Response(预连接响应)"
appdu[130]= "CONNECT-Response(断开应用连接通知)"
appdu[131]= "RELEASE-Response(断开应用连接响应)"
appdu[132]= "RELEASE-Notification(建立应用连接响应)"
appdu[133]= "GET-Response(读取响应)"
appdu[134]= "SET-Response(设置响应)"
appdu[135]= "ACTION-Response(操作响应)"
appdu[136]= "REPORT-Notification(上报通知)"
appdu[137]= "PROXY-Response(代理响应)"
appdu[238]= "ERROR-Response(异常响应)"

OMD = {}

OMD["4000"] = "日期时间"
OMD["4001"] = "通信地址"
OMD["4002"] = "表号"
OMD["4003"] = "客户编号"
OMD["4300"] = "电气设备"

OMD["6000"] = "采集档案配置表"
OMD["6001"] = "采集档案配置单元"
OMD["6002"] = "搜表"
OMD["6003"] = "一个搜表结果"
OMD["6004"] = "一个跨台区结果"
OMD["6012"] = "任务配置表"
OMD["6013"] = "任务配置单元"
OMD["6014"] = "普通采集方案集"
OMD["6015"] = "普通采集方案"
OMD["6016"] = "事件采集方案集"
OMD["6017"] = "事件采集方案"
OMD["6018"] = "透明方案集"
OMD["6019"] = "透明方案"
OMD["601A"] = "透明方案结果集"
OMD["601B"] = "一个透明方案结果"
OMD["601C"] = "上报方案集"
OMD["601D"] = "上报方案"
OMD["6032"] = "采集状态集"
OMD["6033"] = "一个采集状态"
OMD["6034"] = "采集任务监控集"
OMD["6035"] = "采集任务监控单元"
OMD["6040"] = "采集启动时标"
OMD["6041"] = "采集成功时标"
OMD["6042"] = "采集存储时标"

function parse_1(idx)
    if idx == 0 then
        return "0(登录)"
    elseif idx == 1 then
        return "1(心跳)"
    elseif idx == 1 then
        return "2(退出登录)"
    else
        return idx .. ""
    end
end

function parse_4300(idx)
    if idx == 1 then
        return "1(复位)"
    elseif idx == 2 then
        return "2(执行)"
    elseif idx == 3 then
        return "3(数据初始化)"
    elseif idx == 4 then
        return "4(恢复出厂参数)"
    elseif idx == 5 then
        return "5(事件初始化)"
    else 
        return idx .. ""
    end
end
function parse_6000(idx)
    if idx == 2 then
        return "2(配置表)"
    elseif idx == 127 then
        return "127(Add采集档案配置单元)"
    elseif idx == 128 then
        return "128(AddBatch采集档案配置单元)"
    elseif idx == 129 then
        return "129(Update参数)"
    elseif idx == 130 then
        return "130(Update参数)"
    elseif idx == 131 then
        return "131(Delete配置序号)"
    elseif idx == 132 then
        return "132(Delete基本信息)"
    elseif idx == 133 then
        return "133(Delete参数)"
    elseif idx == 134 then
        return "134(Clear参数)"
    else 
        return idx .. ""
    end
end
function parse_6012(idx)
    if idx == 2 then
        return "2(配置表)"
    elseif idx == 3 then
        return "3(记录表)"
    elseif idx == 127 then
        return "127(Add任务配置单元)"
    elseif idx == 128 then
        return "128(Delete任务ID)"
    elseif idx == 129 then
        return "129(Clear参数)"
    elseif idx == 130 then
        return "130(Update参数)"
    else 
        return idx .. ""
    end
end
function parse_6014(idx)
    if idx == 2 then
        return "2(普通采集方案)"
    elseif idx == 127 then
        return "127(Add普通采集方案)"
    elseif idx == 128 then
        return "128(Delete方案编号)"
    elseif idx == 129 then
        return "129(Clear参数)"
    elseif idx == 130 then
        return "130(Set_CSD)"
    else 
        return idx .. ""
    end
end
function parse_6016(idx)
    if idx == 2 then
        return "2(事件采集方案)"
    elseif idx == 127 then
        return "127(Add事件采集方案)"
    elseif idx == 128 then
        return "128(Delete方案编号)"
    elseif idx == 129 then
        return "129(Clear参数)"
    elseif idx == 130 then
        return "130(UpdateReportFlag)"
    else 
        return idx .. ""
    end
end
function parse_601C(idx)
    if idx == 2 then
        return "2(上报方案)"
    elseif idx == 127 then
        return "127(Add上报方案)"
    elseif idx == 128 then
        return "128(Delete方案编号)"
    elseif idx == 129 then
        return "129(Clear参数)"
    else 
        return idx .. ""
    end
end

function parse_129(idx)
    local s = string.format("%02X", idx);
    if idx&0x80 == 0x0080 then
        s = s .. "(可信"
    else
        s = s .. "(不可信"
    end
    if idx&0x3 == 0 then
        s = s .. ", 成功)"
    elseif idx&0x3 == 1 then
        s = s .. ", 地址重复)"
    elseif idx&0x3 == 2 then
        s = s .. ", 非法设备)"
    elseif idx&0x3 == 2 then
        s = s .. ", 容量不足)"
    end
    return s
end

function parse_dlt698_frame(hex_str)
    local start = string.sub(hex_str, 1, 2)
    local len = tonumber(string.reverse(string.sub(hex_str, 3, 6)), 16) 
    local control = string.sub(hex_str, 7, 8)
    local server_addr = string.sub(hex_str, 9, 20)
    local checksum_header = string.sub(hex_str, 21, 24)
    local apdu = string.sub(hex_str, 25, -6)
    local checksum_frame = string.sub(hex_str, -6, -4)
    local end_marker = string.sub(hex_str, -2)

    local appdu_idx  = tonumber(string.sub(apdu, 5, 6), 16)
    local appdu_idx2 = tonumber(string.sub(apdu, 7, 8), 16)
    
    local attribute = ""
    if appdu_idx == 1 then
        attribute = string.format("%s", parse_1(tonumber(string.sub(apdu, 9, 10), 16)))
    elseif appdu_idx == 129 then
        attribute = string.format("%s", parse_129(tonumber(string.sub(apdu, 9, 10), 16)))
    elseif appdu_idx == 7 or appdu_idx == 5 or appdu_idx == 133 or appdu_idx == 135 then
        if appdu_idx2 == 2 then
            attribute = string.format("读取%s个对象属性的响应", string.sub(apdu, 11, 12))
        elseif appdu_idx2 == 5 then
            attribute = "读取分帧传输的下一帧的响应"
        else
-- --[[
            local omd_str = string.upper(string.sub(apdu, 11, 14))
            
            if OMD[omd_str] == nil then
                if omd_str == "4000" then
                    attribute = string.format("%s:%s - %d(主站校时(0)，心跳校时(1)，北斗/GPS(2))", 
                        omd_str, omd_str, tonumber(string.sub(apdu, 15, 16), 16))
                else
                    attribute = string.format("%s:%s - %d", 
                        omd_str, omd_str, tonumber(string.sub(apdu, 15, 16), 16))
                end
            elseif omd_str == "4300" then
                attribute = string.format("%s:%s - %s", 
                    omd_str, OMD[omd_str], parse_4300(tonumber(string.sub(apdu, 15, 16), 16)))
            elseif omd_str == "6000" then
                attribute = string.format("%s:%s - %s", 
                    omd_str, OMD[omd_str], parse_6000(tonumber(string.sub(apdu, 15, 16), 16)))
            elseif omd_str == "6012" then
                attribute = string.format("%s:%s - %s", 
                    omd_str, OMD[omd_str], parse_6012(tonumber(string.sub(apdu, 15, 16), 16)))
            elseif omd_str == "6014" then
                attribute = string.format("%s:%s - %s", 
                    omd_str, OMD[omd_str], parse_6014(tonumber(string.sub(apdu, 15, 16), 16)))
            elseif omd_str == "6016" then
                attribute = string.format("%s:%s - %s", 
                    omd_str, OMD[omd_str], parse_6016(tonumber(string.sub(apdu, 15, 16), 16)))
            elseif omd_str == "601C" then
                attribute = string.format("%s:%s - %s", 
                    omd_str, OMD[omd_str], parse_601C(tonumber(string.sub(apdu, 15, 16), 16)))
            else
                attribute = string.format("%s:%s - %d", 
                    omd_str, OMD[omd_str], tonumber(string.sub(apdu, 15, 16), 16))
            end
--]]
        end
    end

    if appdu[appdu_idx] ~= nil then
        return  string.format("%s %s %s", 
            server_addr, 
            string.format("%02X(%d):%s", appdu_idx, appdu_idx, appdu[appdu_idx]), 
            attribute)
    else
        return nil
    end
end
